package com.ahzx.utils;

import com.jcraft.jsch.*;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

/**
 * sftp
 */
@Component
public class FileToSftp {

    private static final Logger log = LoggerFactory.getLogger(FileToSftp.class);
    /**
     * SFTP 数据传输超时时间
     */
    private int timeout = 30000;

	@Value("${sftp.host}")
	private String sftpHost;
	@Value("${sftp.port}")
	private String sftpPort;
	@Value("${sftp.username}")
	private String sftpName;
	@Value("${sftp.password}")
	private String sftpPassword;
    /**
     * 创建sftp通信通道
     *
     * @param session
     * @return
     */
    public ChannelSftp getSftpClient(Session session) {
        ChannelSftp sftp = null;
        try {
            //创建sftp通信通道
            Channel channel = (Channel) session.openChannel("sftp");
            channel.connect(15000);
            sftp = (ChannelSftp) channel;
        } catch (Exception e) {
            throw new ServiceException("SFTP服务器登录失败");
        }
        return sftp;
    }

    public Session getSftpSession(String sftpServerAddress) {
        Session session = null;
        try {
            JSch jsch = new JSch();
            //采用指定的端口连接服务器
            log.info("sftp地址 -{}, sftp端口 -{}, sftp用户 -{}", sftpServerAddress, sftpPort, sftpName);
            session = jsch.getSession(sftpName, sftpServerAddress, Integer.valueOf(sftpPort));
            //如果服务器连接不上，则抛出异常
            if (session == null) {
                throw new ServiceException("SFTP服务器登录失败");
            }
            //设置登陆主机的密码
            session.setPassword(sftpPassword);
            //设置第一次登陆的时候提示，可选值：(ask | yes | no)
            session.setConfig("StrictHostKeyChecking", "no");
            //设置登陆超时时间
            session.connect(timeout);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return session;
    }

	/**
	 *  创建目标文件夹
	 * @param sftptemp 传输渠道
	 * @param dirName  目标文件夹: "home/wasadmin/record/webapply"
	 * @param rootFlag 是否需要从根目录进入  true:是,false：否
	 */
    public void mkdirFile(ChannelSftp sftptemp, String dirName, boolean rootFlag) {
        if (dirName.indexOf("\\") != -1) {
            dirName = dirName.replaceAll("\\", "/");
        }
        String[] dirs = (dirName.substring(1)).split("/");
        try {
            if (rootFlag) {
                sftptemp.cd("/");
            }
            for (int i = 0; i < dirs.length; i++) {
                try {
                    sftptemp.cd(dirs[i]);
                } catch (SftpException ex) {
                    sftptemp.mkdir(dirs[i]);
                    sftptemp.cd(dirs[i]);
                }
            }
        } catch (Exception e) {
			throw new ServiceException("SFTP IO异常");
        }
    }


	/**
	 * sftp上传文件
	 * @param sftptemp 传输渠道
	 * @param fileName  如果fileName为空,则上传当前文件夹下所有文件
	 * @param dstName
	 */
    public void uploadFile(ChannelSftp sftptemp, String fileName, String dstName) {
        FileInputStream fi = null;
        try {
            if (StringUtils.isEmpty(fileName)) {
                String nowPath = sftptemp.pwd();
                @SuppressWarnings("unchecked")
                Vector<LsEntry> v = sftptemp.ls(nowPath);
                List<Map<String, String>> fileList = buildFiles(v);
                if (fileList.size() > 0) {
                    for (Map<String, String> file : fileList) {
                        if (StringUtils.equals("false", file.get("dir"))) {
                            String fileNameTemp = file.get("name");
                            File fileTemp = new File(fileNameTemp);
                            fi = new FileInputStream(fileTemp);
                            sftptemp.put(fi, fileTemp.getName());
                            fi.close();
                        }
                    }
                }
            } else {
                File file = new File(fileName);
                fi = new FileInputStream(file);
                sftptemp.put(fi, dstName);
                fi.close();
            }
        } catch (Exception e) {
            try {
                if (fi != null) {
                    fi.close();
                }
            } catch (IOException e1) {
                fi = null;
            }
            e.printStackTrace();
			throw new ServiceException("文件传输失败");
        } finally {
            try {
                if (fi != null) {
                    fi.close();
                }
            } catch (IOException e2) {
                fi = null;
            }
        }

    }

	/**
	 * 获取当前文件夹下文件列表
	 * @param ls
	 * @return
	 */
	public List<Map<String, String>> buildFiles(Vector<LsEntry> ls) {
        if (ls != null && ls.size() >= 0) {
            List<Map<String, String>> list = new ArrayList<Map<String, String>>();
            for (int i = 0; i < ls.size(); i++) {
                LsEntry f = (LsEntry) ls.get(i);
                String nm = f.getFilename();
                if (StringUtils.equals(nm, ".") || StringUtils.equals(nm, "..")) {
					continue;
				}
                SftpATTRS attr = f.getAttrs();
                Map<String, String> map = new HashMap<String, String>();
                if (attr.isDir()) {
                    map.put("dir", "true");
                } else {
                    map.put("dir", "false");
                }
                map.put("name", nm);
                list.add(map);
            }
            return list;
        }
        return null;
    }
}
